﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Linq;
using Hxsoft.AppV1;

namespace Hxsoft.AppV1.Module
{
	public partial class Link : ICreator { }




	/// <summary>
	/// Links 类。
	/// </summary>
	public static partial class Links
	{
		public const string INFO_TYPE = "Link";



		#region GetItem
		/// <summary>
		/// 根据标识获取指定的链接。
		/// </summary>
		/// <param name="o">链接集合。</param>
		/// <param name="linkId">获取的链接标识 LinkId。</param>
		/// <returns>获取的信息项。</returns>
		public static Link GetItem(this System.Data.Linq.Table<Link> o, int linkId)
		{
			return o.SingleOrDefault(p => p.LinkId == linkId);
		}

		public static Link GetItem(int linkId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;
			return dc.Links.GetItem(linkId);
		}
		#endregion



		#region Exists
		/// <summary>
		/// 验证指定的链接是否已经存在。
		/// </summary>
		/// <param name="o">链接集合。</param>
		/// <param name="linkId">验证的链接标识 LinkId。</param>
		/// <returns>布尔值表示指定的链接是否已经存在。</returns>
		public static bool Exists(this System.Data.Linq.Table<Link> o, int linkId)
		{
			return o.Any(p => p.LinkId == linkId);
		}
		#endregion
	}



	/// <summary>
	/// Links 类操作部分。
	/// </summary>
	public static partial class Links
	{
		#region Insert
		/// <summary>
		/// 添加链接。
		/// </summary>
		/// <param name="insertedLink">添加的链接。</param>
		/// <returns>添加的链接。</returns>
		public static Link Insert(Link insertedLink)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Link link = insertedLink.ToNewEntity<Link>();
			link.IsEffective = false;
			link.OrderNumber = null;
			link.CreatorId = Users.CurrentUserId;
			link.CreationDate = DateTime.Now;

			GetInsertRight(dc, link, true);	// 权限验证

			dc.Links.InsertOnSubmit(link);
			dc.SubmitChanges();

			// 持久化资源
			InfoItems.SetPersistent(dc, link.GlobalId, true);

			// 记录日志
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(link.ClassId);
			Logs.Insert(dc, resourceId, (int)LinkClasses.LinkReleasePermissionCode.Insert, INFO_TYPE, link.LinkId.ToString(), LinkClasses.LinkReleasePermissionCode.Insert.ToString(), link.Title);

			// 返回只读数据
			return insertedLink.FillByEntity(link);
		}
		#endregion



		#region Update
		private static readonly HashSet<string> _updatedExcludeColumns = typeof(Link).GetEntityColumnNames(new string[] {
				"LinkId",
				"ClassId",
				"IsEffective",
				"CreationDate",
				"CreatorId",
				"GlobalId",
				"OrderNumber",
				"ChannelIds"
			}, true);

		/// <summary>
		/// 修改链接。
		/// </summary>
		/// <param name="updatedLink">修改的链接。</param>
		/// <returns>修改的链接。</returns>
		public static Link Update(Link updatedLink)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Link link = dc.Links.GetItem(updatedLink.LinkId);
			if (link == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetUpdateRight(dc, link, true);	// 权限验证

			link.FillByEntity(updatedLink, EntityColumnsSetType.Exclude, _updatedExcludeColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 持久化资源
			InfoItems.SetPersistent(dc, link.GlobalId, true);

			// 记录日志
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(link.ClassId);
			Logs.Insert(dc, resourceId, (int)LinkClasses.LinkReleasePermissionCode.Update, INFO_TYPE, link.LinkId.ToString(), LinkClasses.LinkReleasePermissionCode.Update.ToString(), link.Title);

			// 返回只读数据
			return updatedLink.FillByEntity(link);
		}
		#endregion



		#region Setting
		private static readonly HashSet<string> _settingColumns = typeof(Link).GetEntityColumnNames(new string[] {
				"IsEffective",
				"OrderNumber",
				"ChannelIds"
			}, true);

		/// <summary>
		/// 设置链接。
		/// </summary>
		/// <param name="settedLink">设置的链接。</param>
		/// <returns>设置的链接。</returns>
		public static Link Setting(Link settedLink)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Link link = dc.Links.GetItem(settedLink.LinkId);
			if (link == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSettingRight(dc, link, true);	// 权限验证

			link.FillByEntity(settedLink, _settingColumns);

			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(link.ClassId);
			Logs.Insert(dc, resourceId, (int)LinkClasses.LinkReleasePermissionCode.Setting, INFO_TYPE, link.LinkId.ToString(), LinkClasses.LinkReleasePermissionCode.Setting.ToString(), link.Title);

			// 返回只读数据
			return settedLink.FillByEntity(link);
		}
		#endregion



		#region SetEffectiveState
		/// <summary>
		/// 设置信息的有效状态。
		/// </summary>
		/// <param name="linkId">设置的信息标识。</param>
		public static void SetEffectiveState(int linkId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Link link = dc.Links.GetItem(linkId);
			if (link == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSetEffectiveStateRight(dc, link, true);	// 权限验证

			link.IsEffective = !link.IsEffective;
			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(link.ClassId);
			Logs.Insert(dc, resourceId, (int)LinkClasses.LinkReleasePermissionCode.Setting, INFO_TYPE, link.LinkId.ToString(), LinkClasses.LinkReleasePermissionCode.Setting.ToString() + "/EffectiveState", link.Title);
		}

		/// <summary>
		/// 设置信息的有效状态。
		/// </summary>
		/// <param name="linkId">设置的信息标识。</param>
		/// <param name="state">设置的状态。</param>
		public static void SetEffectiveState(int linkId, bool state)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Link link = dc.Links.GetItem(linkId);
			if (link == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetSetEffectiveStateRight(dc, link, true);	// 权限验证

			if (link.IsEffective == state)
				return;

			link.IsEffective = state;
			try
			{
				dc.SubmitChanges(ConflictMode.ContinueOnConflict);
			}
			catch (ChangeConflictException e)
			{
				foreach (ObjectChangeConflict occ in dc.ChangeConflicts)
				{
					occ.Resolve(RefreshMode.KeepCurrentValues);
				}
			}

			// 记录日志
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(link.ClassId);
			Logs.Insert(dc, resourceId, (int)LinkClasses.LinkReleasePermissionCode.Setting, INFO_TYPE, link.LinkId.ToString(), LinkClasses.LinkReleasePermissionCode.Setting.ToString() + "/EffectiveState", link.Title);
		}
		#endregion



		#region Delete
		/// <summary>
		/// 删除链接。
		/// </summary>
		/// <param name="linkId">删除的链接标识 LinkId。</param>
		public static void Delete(int linkId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();

			Link link = dc.Links.GetItem(linkId);
			if (link == null)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			GetDeleteRight(dc, link, true);	// 权限验证

			Delete(dc, link);

			dc.SubmitChanges();

			// 记录日志
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(link.ClassId);
			Logs.Insert(dc, resourceId, (int)LinkClasses.LinkReleasePermissionCode.Delete, INFO_TYPE, link.LinkId.ToString(), LinkClasses.LinkReleasePermissionCode.Delete.ToString(), link.Title);
		}

		#region internal Delete
		internal static void Delete(GenericModuleDataContext dc, Link link)
		{
			dc.Links.DeleteOnSubmit(link);

			// 删除资源
			InfoItem infoItem = dc.InfoItems.GetItem(link.GlobalId);
			if (infoItem != null)
				InfoItems.Delete(dc, infoItem);
		}

		internal static void DeleteByParent(GenericModuleDataContext dc, LinkClass parent)
		{
			IEnumerable<Link> e = parent.Links.AsEnumerable();
			foreach (Link i in e)
				Delete(dc, i);
		}
		#endregion
		#endregion
	}



	/// <summary>
	/// Links 类对应操作权限部分。
	/// </summary>
	public static partial class Links
	{
		#region GetInsertRight
		/// <summary>
		/// 获取当前用户是否有添加链接的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="link">添加的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加链接的权限。</returns>
		public static bool GetInsertRight(GenericModuleDataContext dc, Link link, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)LinkClasses.LinkReleasePermissionCode.Insert;
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(dc.LinkClasses.GetItem(link.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Link>(userName, link, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, link, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有添加链接的权限。
		/// </summary>
		/// <param name="link">添加的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有添加链接的权限。</returns>
		public static bool GetInsertRight(Link link, bool triggerException)
		{
			return GetInsertRight(new GenericModuleDataContext(), link, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有添加链接的权限。
		/// </summary>
		/// <param name="link">添加的链接对象。</param>
		/// <returns>布尔值表示当前用户是否有添加链接的权限。</returns>
		public static bool GetInsertRight(Link link)
		{
			return GetInsertRight(link, false);
		}
		#endregion



		#region GetUpdateRight
		/// <summary>
		/// 获取当前用户是否有更新链接的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="link">更新的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新链接的权限。</returns>
		public static bool GetUpdateRight(GenericModuleDataContext dc, Link link, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)LinkClasses.LinkReleasePermissionCode.Update;
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(dc.LinkClasses.GetItem(link.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Link>(userName, link, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, link, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有更新链接的权限。
		/// </summary>
		/// <param name="link">更新的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有更新链接的权限。</returns>
		public static bool GetUpdateRight(Link link, bool triggerException)
		{
			return GetUpdateRight(new GenericModuleDataContext(), link, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有更新链接的权限。
		/// </summary>
		/// <param name="link">更新的链接对象。</param>
		/// <returns>布尔值表示当前用户是否有更新链接的权限。</returns>
		public static bool GetUpdateRight(Link link)
		{
			return GetUpdateRight(link, false);
		}
		#endregion



		#region GetDeleteRight
		/// <summary>
		/// 获取当前用户是否有删除链接的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="link">删除的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除链接的权限。</returns>
		public static bool GetDeleteRight(GenericModuleDataContext dc, Link link, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)LinkClasses.LinkReleasePermissionCode.Delete;
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(dc.LinkClasses.GetItem(link.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Link>(userName, link, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, link, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有删除链接的权限。
		/// </summary>
		/// <param name="link">删除的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有删除链接的权限。</returns>
		public static bool GetDeleteRight(Link link, bool triggerException)
		{
			return GetDeleteRight(new GenericModuleDataContext(), link, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有删除链接的权限。
		/// </summary>
		/// <param name="link">删除的链接对象。</param>
		/// <returns>布尔值表示当前用户是否有删除链接的权限。</returns>
		public static bool GetDeleteRight(Link link)
		{
			return GetDeleteRight(link, false);
		}
		#endregion



		#region GetSettingRight
		/// <summary>
		/// 获取当前用户是否有设置链接的权限。
		/// </summary>
		/// <param name="dc">数据容器。</param>
		/// <param name="link">设置的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有设置链接的权限。</returns>
		public static bool GetSettingRight(GenericModuleDataContext dc, Link link, bool triggerException)
		{
			string userName = Users.CurrentUserName;
			int permissionCode = (int)LinkClasses.LinkReleasePermissionCode.Setting;
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(dc.LinkClasses.GetItem(link.ClassId));
			if (!resourceId.HasValue)
				throw new ObjectNotExistsException(Res.Resources_NotExistsResource);

			bool b = dc.AccessController.GetUserIsHasPermission<Link>(userName, link, resourceId.Value, permissionCode);

			if (triggerException && !b)
				throw new PermissionException(userName, link, resourceId.Value, permissionCode, Res.PermissionExceptionMessage);
			return b;
		}

		/// <summary>
		/// 获取当前用户是否有设置链接的权限。
		/// </summary>
		/// <param name="link">设置的链接对象。</param>
		/// <param name="triggerException">当未通过权限验证的时候是否引发异常。</param>
		/// <returns>布尔值表示当前用户是否有设置链接的权限。</returns>
		public static bool GetSettingRight(Link link, bool triggerException)
		{
			return GetSettingRight(new GenericModuleDataContext(), link, triggerException);
		}

		/// <summary>
		/// 获取当前用户是否有设置链接的权限。
		/// </summary>
		/// <param name="link">设置的链接对象。</param>
		/// <returns>布尔值表示当前用户是否有设置链接的权限。</returns>
		public static bool GetSettingRight(Link link)
		{
			return GetSettingRight(link, false);
		}



		public static bool GetSetEffectiveStateRight(GenericModuleDataContext dc, Link link, bool triggerException)
		{
			return GetSettingRight(dc, link, triggerException);
		}

		public static bool GetSetEffectiveStateRight(Link link, bool triggerException)
		{
			return GetSetEffectiveStateRight(new GenericModuleDataContext(), link, triggerException);
		}

		public static bool GetSetEffectiveStateRight(Link link)
		{
			return GetSetEffectiveStateRight(link, false);
		}
		#endregion
	}




	/// <summary>
	/// Links 类后台管理部分。
	/// </summary>
	public static partial class Links
	{
		public static bool GetManageListRight()
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			return dc.AccessController.GetUserIsHasCategoryPermission<object>(Users.CurrentUserName, null, LinkClasses.LinkReleaseResourceCategoryId, (int)LinkClasses.LinkReleasePermissionCode.Update, App.Context.CurrentSiteId);
		}

		public static bool GetManageListRight(int classId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(classId);
			if (resourceId == null) return false;
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, resourceId.Value, (int)LinkClasses.LinkReleasePermissionCode.Insert, Sites.CurrentSiteId);
		}

		public static bool GetManageListRight(int classId,int? siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseResourceId(classId);
			if (resourceId == null) return false;
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, resourceId.Value, (int)LinkClasses.LinkReleasePermissionCode.Insert, siteId);
		}

		public static bool GetRootManageListRight(int siteId)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			Guid? resourceId = dc.LinkClasses.GetLinkReleaseRootResourceId(siteId);
			if (resourceId == null) return false;
			return dc.AccessController.GetUserIsHasPermission<object>(Users.CurrentUserName, null, resourceId.Value, (int)LinkClasses.LinkReleasePermissionCode.Insert, siteId);
		}



		public struct LinkForManageList
		{
			public int LinkId { get; set; }
			public string Title { get; set; }
			public DateTime? StartDate { get; set; }
			public DateTime? EndDate { get; set; }
			public int? OrderNumber { get; set; }
			public bool IsEffective { get; set; }
			public string Describe { get; set; }
			public DateTime CreationDate { get; set; }
			public string ChannelIds { get; set; }
		}

		public static PaginationInfo<List<LinkForManageList>> GetPaginationManageList(int classId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Links
					where p.ClassId == classId
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForManageList
					{
						LinkId = p.LinkId,
						Title = p.Title,
						StartDate = p.StartDate,
						EndDate = p.EndDate,
						OrderNumber = p.OrderNumber,
						IsEffective = p.IsEffective,
						CreationDate = p.CreationDate,
						Describe=p.LinkWords
					};

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));

			PaginationInfo<List<LinkForManageList>> pageInfo = new PaginationInfo<List<LinkForManageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static PaginationInfo<List<LinkForManageList>> GetPaginationManageList(int classId,int? channelId, string keyword, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = from p in dc.Links
					where p.ClassId == classId
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForManageList
					{
						LinkId = p.LinkId,
						Title = p.Title,
						StartDate = p.StartDate,
						EndDate = p.EndDate,
						OrderNumber = p.OrderNumber,
						IsEffective = p.IsEffective,
						CreationDate = p.CreationDate,
						Describe = p.LinkWords,
						ChannelIds = p.ChannelIds
					};

			if (!string.IsNullOrEmpty(keyword))
				q = q.Where(p => p.Title.Contains(keyword));
			
			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			PaginationInfo<List<LinkForManageList>> pageInfo = new PaginationInfo<List<LinkForManageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}
	}

	/// <summary>
	/// Links 类对应前端数据读取部分。
	/// </summary>
	public static partial class Links
	{
		public struct LinkForImageList
		{
			public int LinkId { get; set; }
			public string ImageType { get; set; }
			public string LinkUrl { get; set; }
			public string Title { get; set; }
			public DateTime CreationDate { get; set; }
			public string Describe { get; set; }
			public string ChannelIds { get; set; }
		}



		private static IQueryable<LinkForImageList> GetImageListQuery(GenericModuleDataContext dc, int classId)
		{
			var q = from p in dc.Links
					where p.ClassId == classId
						&& p.IsEffective == true
						&& p.StartDate <= DateTime.Now && (p.EndDate == null || p.EndDate > DateTime.Now)
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForImageList
					{
						LinkId = p.LinkId,
						ImageType = p.ImageType,
						LinkUrl = p.LinkUrl,
						Title = p.Title,
						Describe=p.LinkWords,
						CreationDate = p.CreationDate
					};
			return q;
		}

		public static PaginationInfo<List<LinkForImageList>> GetPaginationImageList(int classId, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<LinkForImageList> q = GetImageListQuery(dc, classId);

			PaginationInfo<List<LinkForImageList>> pageInfo = new PaginationInfo<List<LinkForImageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<LinkForImageList> GetImageList(int classId, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetImageListQuery(dc, classId);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}

		
		private static IQueryable<LinkForImageList> GetImageListQuery(GenericModuleDataContext dc, int classId, int? channelId)
		{
			var q = from p in dc.Links
					where p.ClassId == classId
						&& p.IsEffective == true
						&& p.StartDate <= DateTime.Now && (p.EndDate == null || p.EndDate > DateTime.Now)
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForImageList
					{
						LinkId = p.LinkId,
						ImageType = p.ImageType,
						LinkUrl = p.LinkUrl,
						Title = p.Title,
						Describe = p.LinkWords,
						CreationDate = p.CreationDate,
						ChannelIds = p.ChannelIds
					};
			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			return q;
		}

		public static PaginationInfo<List<LinkForImageList>> GetPaginationImageList(int classId, int? channelId, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<LinkForImageList> q = GetImageListQuery(dc, classId, channelId);

			PaginationInfo<List<LinkForImageList>> pageInfo = new PaginationInfo<List<LinkForImageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<LinkForImageList> GetImageList(int classId, int? channelId, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetImageListQuery(dc, classId, channelId);

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}



		private static IQueryable<LinkForImageList> GetImageListQuery(GenericModuleDataContext dc, string classCode)
		{
			var q = from p in dc.Links
					from p1 in dc.LinkClasses
					where p.ClassId == p1.ClassId
						&& p1.ClassCode == classCode
						&& p.IsEffective == true
						&& p.StartDate <= DateTime.Now && (p.EndDate == null || p.EndDate > DateTime.Now)
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForImageList
					{
						LinkId = p.LinkId,
						ImageType = p.ImageType,
						LinkUrl = p.LinkUrl,
						Title = p.Title,
						Describe=p.LinkWords,
						CreationDate = p.CreationDate
					};

			return q;
		}		

		public static PaginationInfo<List<LinkForImageList>> GetPaginationImageList(int? siteId, string classCode, int pageSize, int currentPage)
		{
			if (siteId.HasValue) return GetPaginationImageList(siteId.Value, classCode, pageSize, currentPage);

			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<LinkForImageList> q = GetImageListQuery(dc, classCode);

			PaginationInfo<List<LinkForImageList>> pageInfo = new PaginationInfo<List<LinkForImageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<LinkForImageList> GetImageList(int? siteId, string classCode, int? loadCount)
		{
			return GetImageList(siteId, classCode, false, loadCount);
		}

		public static List<LinkForImageList> GetImageList(int? siteId, string classCode, bool randomSort, int? loadCount)
		{
			if (siteId.HasValue) return GetImageList(siteId.Value, classCode, randomSort, loadCount);

			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetImageListQuery(dc, classCode);
			if (randomSort)
				q = q.OrderBy(e => dc.NEWID());

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}



		private static IQueryable<LinkForImageList> GetImageListQuery(GenericModuleDataContext dc, string classCode, int? channelId)
		{
			var q = from p in dc.Links
					from p1 in dc.LinkClasses
					where p.ClassId == p1.ClassId
						&& p1.ClassCode == classCode
						&& p.IsEffective == true
						&& p.StartDate <= DateTime.Now && (p.EndDate == null || p.EndDate > DateTime.Now)
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForImageList
					{
						LinkId = p.LinkId,
						ImageType = p.ImageType,
						LinkUrl = p.LinkUrl,
						Title = p.Title,
						Describe = p.LinkWords,
						CreationDate = p.CreationDate,
						ChannelIds = p.ChannelIds
					};

			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			return q;
		}
		public static PaginationInfo<List<LinkForImageList>> GetPaginationImageList(int? siteId, string classCode, int? channelId, int pageSize, int currentPage)
		{
			if (siteId.HasValue) return GetPaginationImageList(siteId.Value, classCode, channelId, pageSize, currentPage);

			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<LinkForImageList> q = GetImageListQuery(dc, classCode, channelId);

			PaginationInfo<List<LinkForImageList>> pageInfo = new PaginationInfo<List<LinkForImageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<LinkForImageList> GetImageList(int? siteId, string classCode, int? channelId, int? loadCount)
		{
			return GetImageList(siteId, classCode, channelId, false, loadCount);
		}

		public static List<LinkForImageList> GetImageList(int? siteId, string classCode, int? channelId, bool randomSort, int? loadCount)
		{
			if (siteId.HasValue) return GetImageList(siteId.Value, classCode, channelId, randomSort, loadCount);

			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetImageListQuery(dc, classCode, channelId);
			if (randomSort)
				q = q.OrderBy(e => dc.NEWID());

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}




		private static IQueryable<LinkForImageList> GetImageListQuery(GenericModuleDataContext dc, int siteId, string classCode)
		{
			int? classId = dc.LinkClasses.GetIdentifier(siteId, classCode);
			if (!classId.HasValue)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			var q = from p in dc.Links
					where p.ClassId == classId.Value
						&& p.IsEffective == true
						&& p.StartDate <= DateTime.Now && (p.EndDate == null || p.EndDate > DateTime.Now)
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForImageList
					{
						LinkId = p.LinkId,
						ImageType = p.ImageType,
						LinkUrl = p.LinkUrl,
						Title = p.Title,
						Describe=p.LinkWords,
						CreationDate = p.CreationDate
					};
			return q;
		}

		public static PaginationInfo<List<LinkForImageList>> GetPaginationImageList(int siteId, string classCode, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<LinkForImageList> q = GetImageListQuery(dc, siteId, classCode);

			PaginationInfo<List<LinkForImageList>> pageInfo = new PaginationInfo<List<LinkForImageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<LinkForImageList> GetImageList(int siteId, string classCode, int? loadCount)
		{
			return GetImageList(siteId, classCode, false, loadCount);
		}

		public static List<LinkForImageList> GetImageList(int siteId, string classCode, bool randomSort, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetImageListQuery(dc, siteId, classCode);
			if (randomSort)
				q = q.OrderBy(e => dc.NEWID());

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}


		private static IQueryable<LinkForImageList> GetImageListQuery(GenericModuleDataContext dc, int siteId, string classCode, int? channelId)
		{
			int? classId = dc.LinkClasses.GetIdentifier(siteId, classCode);
			if (!classId.HasValue)
				throw new ObjectNotExistsException(Res.Operation_ObjectNotExists);

			var q = from p in dc.Links
					where p.ClassId == classId.Value
						&& p.IsEffective == true
						&& p.StartDate <= DateTime.Now && (p.EndDate == null || p.EndDate > DateTime.Now)
					orderby p.OrderNumber descending, p.StartDate descending, p.CreationDate descending
					select new LinkForImageList
					{
						LinkId = p.LinkId,
						ImageType = p.ImageType,
						LinkUrl = p.LinkUrl,
						Title = p.Title,
						Describe = p.LinkWords,
						CreationDate = p.CreationDate,
						ChannelIds = p.ChannelIds
					};

			if (channelId.HasValue)
			{
				string channels = Dictionaries.BuildDicCombineValues<int>(channelId.Value);
				q = q.Where(p => p.ChannelIds.Contains(channels));
			}

			return q;
		}

		public static PaginationInfo<List<LinkForImageList>> GetPaginationImageList(int siteId, string classCode, int? channelId, int pageSize, int currentPage)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			IQueryable<LinkForImageList> q = GetImageListQuery(dc, siteId, classCode, channelId);

			PaginationInfo<List<LinkForImageList>> pageInfo = new PaginationInfo<List<LinkForImageList>>();
			pageInfo.PageSize = pageSize;
			pageInfo.CurrentPage = currentPage;
			pageInfo.RecordCount = q.Count();
			pageInfo.Records = q.Skip((currentPage - 1) * pageSize).Take(pageSize).ToList();
			return pageInfo;
		}

		public static List<LinkForImageList> GetImageList(int siteId, string classCode, int? channelId, int? loadCount)
		{
			return GetImageList(siteId, classCode, channelId, false, loadCount);
		}

		public static List<LinkForImageList> GetImageList(int siteId, string classCode, int? channelId, bool randomSort, int? loadCount)
		{
			GenericModuleDataContext dc = new GenericModuleDataContext();
			dc.ObjectTrackingEnabled = false;

			var q = GetImageListQuery(dc, siteId, classCode, channelId);
			if (randomSort)
				q = q.OrderBy(e => dc.NEWID());

			if (loadCount.HasValue)
				return q.Take(loadCount.Value).ToList();
			return q.ToList();
		}
	}
}